package com.hc.java.transaction;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

/**
 * 最原始的方法，Thread run()重写
 *
 * @author huangchao E-mail:fengquan8866@163.com
 * @version 创建时间：2024/6/20 20:34
 */
public class T06_04_AliQuestionAboutCF_2 {

    private enum Result {
        SUCCESS, FAIL, CANCELLED
    }

    static List<MyTask> tasks = new ArrayList<>();


    public static void main(String[] args) throws Exception {
        MyTask t1 = new MyTask("t1", 3, Result.SUCCESS);
        MyTask t2 = new MyTask("t2", 4, Result.SUCCESS);
        MyTask t3 = new MyTask("t3", 1, Result.FAIL);

        tasks.add(t1);
        tasks.add(t2);
        tasks.add(t3);

        for (MyTask task : tasks) {

            CompletableFuture f1 = CompletableFuture.supplyAsync(() -> task.runTask()).thenAccept(r -> callback(r, task));

        }

        System.in.read();
    }

    private static void callback(Result r, MyTask task) {
        if (Result.FAIL == r) {
            for (MyTask _task : tasks) {
                if (_task != task) {
                    task.cancel(); // 加超时处理，加出错处理，设计任务接口
                }
            }
            // 处理结束流程
            // 通知其他线程结束（回滚）
            // 超时处理

        }
    }

    private static class MyTask {
        private String name;
        private int timeInSeconds;
        private Result result;

        volatile boolean cancelling = false;
        volatile boolean cancelled = false;

        public MyTask(String name, int timeInSeconds, Result result) {
            this.name = name;
            this.timeInSeconds = timeInSeconds;
            this.result = result;
        }

        public Result runTask() {
            int interval = 100;
            int total = 0;
            try {
                for (; ; ) {
                    Thread.sleep(timeInSeconds);
                    total += interval;
                    if (total >= timeInSeconds) {
                        break;
                    }
                    if (cancelling) {
                        return Result.CANCELLED;
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println(name + " end!");
            // 模拟业务执行时间
            // 实际中时间不固定，可能在处理计算任务，或者是IO任务
            return result;
        }

        public void cancel() {
            if (!cancelled) {
                synchronized (this) {
                    if (cancelled) return;
                    cancelling = true; // 正在cancel
                    System.out.println(name + "cancelling");
                    try {
                        TimeUnit.MILLISECONDS.sleep(50);
                    } catch (InterruptedException e) {
                        e.printStackTrace(); // 记录日志 通知主线程cancel不掉，考虑干掉
                    }
                    System.out.println(name + "cancelled");
                    cancelled = true;
                    cancelling = true;
                }
            }
        }
    }
}
